package cn.edu.ncu.housinghub.interceptor;

import cn.edu.ncu.housinghub.constant.ErrorCodeConstant;
import cn.edu.ncu.housinghub.constant.SystemConstant;
import cn.edu.ncu.housinghub.entity.user.User;
import cn.edu.ncu.housinghub.exception.BusinessException;
import cn.edu.ncu.housinghub.vo.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Set;

/**
 * 用户角色校验拦截器
 * 用于校验特定操作需要的用户角色
 */
@Component
public class UserRoleCheckInterceptor implements HandlerInterceptor {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        
        // 检查是否需要角色校验
        if (needRoleCheck(requestURI)) {
            // 获取请求头中的token
            String token = request.getHeader("info");
            if (token == null || token.trim().isEmpty()) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(
                    Result.error(ErrorCodeConstant.TOKEN_MISSING.getCode(),
                               ErrorCodeConstant.TOKEN_MISSING.getMessage())
                ));
                return false;
            }

            // 从Redis中查询token对应的用户信息
            Set<String> keys = redisTemplate.keys(SystemConstant.REDIS_TOKEN_PREFIX_USER.getStringValue() + "*:" + token);
            if (keys == null || keys.isEmpty()) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(
                    Result.error(ErrorCodeConstant.TOKEN_INVALID.getCode(),
                               ErrorCodeConstant.TOKEN_INVALID.getMessage())
                ));
                return false;
            }

            String redisKey = keys.iterator().next();
            User user = (User) redisTemplate.opsForValue().get(redisKey);
            if (user == null) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(
                    Result.error(ErrorCodeConstant.TOKEN_INVALID.getCode(),
                               ErrorCodeConstant.TOKEN_INVALID.getMessage())
                ));
                return false;
            }
            
            // 根据不同的URL进行角色校验
            if (!checkUserRole(requestURI, user.getRole())) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(objectMapper.writeValueAsString(
                    Result.error(ErrorCodeConstant.USER_ROLE_NOT_MATCH.getCode(), 
                               ErrorCodeConstant.USER_ROLE_NOT_MATCH.getMessage())
                ));
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 判断当前请求是否需要角色校验
     */
    private boolean needRoleCheck(String requestURI) {
        // 排除登录、注册等不需要角色校验的接口
        if (requestURI.contains("/user/login") ||
            requestURI.contains("/user/register") ||
            requestURI.contains("/user/send-code") ||
            requestURI.contains("/admin/") ||
            requestURI.contains("/test/") ||
            requestURI.contains("/oss/") ||
            requestURI.contains("/upload/") ||
            requestURI.contains("/ws/")) {
            return false;
        }

        // 中介申请：只有普通用户(1)可以申请
        if (requestURI.contains("/agent/auth/apply")) {
            return true;
        }

        // 发布房源/我的房源：只有普通用户(1)和已经成为房东(2)可以操作
        if (requestURI.contains("/house/publish") ||
            requestURI.contains("/house/my-houses") ||
            requestURI.contains("/landlord/publish")) {
            return true;
        }

        // 房东界面：需要房东身份(2)
        if (requestURI.contains("/landlord/") &&
            !requestURI.contains("/landlord/publish")) {
            return true;
        }

        // 中介界面：需要中介身份(4)
        if (requestURI.contains("/agent-rental/")) {
            return true;
        }

        return false;
    }
    
    /**
     * 检查用户角色是否符合要求
     */
    private boolean checkUserRole(String requestURI, Integer userRole) {
        // 中介申请：只有普通用户(1)可以申请
        if (requestURI.startsWith("/agent/auth/apply")) {
            return userRole.equals(SystemConstant.ROLE_TENANT.getIntegerValue());
        }
        
        // 发布房源/我的房源：只有普通用户(1)和已经成为房东(2)可以操作
        if (requestURI.startsWith("/house/publish") ||
            requestURI.startsWith("/house/my-houses") ||
            requestURI.startsWith("/landlord/publish")) {
            return userRole.equals(SystemConstant.ROLE_TENANT.getIntegerValue()) ||
                   userRole.equals(SystemConstant.ROLE_LANDLORD.getIntegerValue());
        }
        
        // 房东界面：需要房东身份(2)
        if (requestURI.startsWith("/landlord/") && 
            !requestURI.startsWith("/landlord/publish")) {
            return userRole.equals(SystemConstant.ROLE_LANDLORD.getIntegerValue());
        }
        
        // 中介界面：需要中介身份(4)
        if (requestURI.startsWith("/agent-rental/")) {
            return userRole.equals(SystemConstant.ROLE_AGENT.getIntegerValue());
        }
        
        return true;
    }
}
